﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.Domain.Request.Waimai;
using Casamiel.Domain.Response;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using MediatR;
using Casamiel.API.Infrastructure;
using Casamiel.Application.Commands.Waimai;
using Newtonsoft.Json;
using System.Globalization;
using Casamiel.Domain.Entity;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Application;
using Casamiel.API.Application.Services;
using Enyim.Caching;
using Newtonsoft.Json.Linq;
using Casamiel.API.Application.Models.ICModels;
using Casamiel.Application.Commands;
using Microsoft.Extensions.Options;
using Casamiel.Domain.Request;
using Casamiel.Domain.Response.Pre;
using Casamiel.Domain.Request.Pre;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Casamiel.API.Controllers.V2.WaiMai
{
    /// <summary>
    /// 外卖订单接口
    /// </summary>
    [ApiVersion("2.0")]
    [Route("api/v{api-version:apiVersion}/WaiMai/[controller]")]
    [ApiController]
    [Authorize]
    [EnableCors("any")]
    public class OrderController : BaseController
    {
        private readonly IMediator _mediator;
        private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("WaimaiService");
        private readonly IIcApiService _icApiService;
        private readonly INetICService _netICService;
        private readonly IStoreService _storeService;
        //private readonly ICasaMielSession _session;
        //private readonly IPaymentService _paymentService;
        //private readonly IMemberCardService _memberCardService;
        private readonly IUserLogService _userLog;
        private readonly IMemcachedClient _memcachedClient;
        private readonly string _memcachedPrex;
        //private readonly INoticeService _notice;
        //private readonly IOrderService _order;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mediator"></param>
        /// <param name="icApiService"></param>
        /// <param name="netICService"></param>
        /// <param name="optionsSnapshot"></param>
        /// <param name="paymentService"></param>
        /// <param name="userLogService"></param>
        /// <param name="storeService"></param>
        /// <param name="memcachedClient"></param>
        public OrderController(IMediator mediator, IIcApiService icApiService, INetICService netICService, IOptionsSnapshot<CasamielSettings> optionsSnapshot, IPaymentService paymentService, IUserLogService userLogService
            , IStoreService storeService, IMemcachedClient memcachedClient)
        {
            _mediator = mediator;
            _icApiService = icApiService;
            _netICService = netICService;
            //_paymentService = paymentService;
            _userLog = userLogService;
            _memcachedPrex = optionsSnapshot.Value.MemcachedPre;
            _storeService = storeService;
            _memcachedClient = memcachedClient;
        }

        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="req"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        [HttpPost]
        [Route("[action]")]
        public async Task<BaseResult<PaymentRsp>> CreateOrder([FromBody] TakeOutOrderCreateRequest req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }

            var Loginfo = this.LoginInfo;
            var mobile = MemberHelper.GetMobile(token);

            var cmd = new CreateOrderCommand(Loginfo.Item3) {
                PayCardNO = req.PayCardNO,
                Paymethod = req.Paymethod,
                ConsigneeId = req.ConsigneeId,
                ContactName = req.ContactName,
                TakeTime = req.TakeTime,
                GoodsList = req.GoodsList,
                Mobile = mobile,
                OrderType = req.OrderType,
                FreightMoney = req.FreightMoney,
                StoreId = req.StoreId,
                Id = req.Id,
                DiscountList = req.DiscountList,
                ContactPhone = req.ContactPhone,
                InvoiceId = req.InvoiceId,
                Remark = req.Remark
            };
            var result = await _mediator.Send(cmd).ConfigureAwait(false);
            logger.Trace($"req:{JsonConvert.SerializeObject(cmd)},{JsonConvert.SerializeObject(result)}");
            if (result.Code == 0 && result.Content.Payed != true) {
                logger.Trace($"{JsonConvert.SerializeObject(result.Content)}");
                var array = result.Content.Paymentrequest.Split(',');
                var p_tradeno = $"C{DateTime.Now.ToString("yyMMddHHmmssfff", CultureInfo.CurrentCulture)}";
                var payment = new PaymentRecord {
                    ShopName = "",
                    OperationMethod = (int)OperationMethod.Waimai,
                    TradeNo = p_tradeno,
                    Amount = array[0].ToDouble(0),
                    PayMethod = req.Paymethod,
                    BillNO = result.Content.OrderCode,
                    IcTradeNO = array[1].ToString(CultureInfo.CurrentCulture),
                    State = 0,
                    OperationState = 0,
                    CreateTime = DateTime.Now,
                    Mobile = mobile
                };

                string shopno;
                var shopinfo = await _storeService.GetByStoreIdAsync<ICasaMielSession>(req.StoreId).ConfigureAwait(false);
                if (shopinfo != null) {
                    payment.ShopName = shopinfo.StoreName;
                    payment.ShopId = shopinfo.RelationId;
                }


                var cachekey = string.Format(CultureInfo.CurrentCulture, Constant.SHOPNO, _memcachedPrex, payment.ShopId);
                shopno = await _memcachedClient.GetValueAsync<string>(cachekey).ConfigureAwait(false);
                if (string.IsNullOrEmpty(shopno)) {
                    var basedata = await _icApiService.BasedataQuery(new BasedataqueryReq { Datatype = 3, Datavalue = $"{payment.ShopId.Value}" }).ConfigureAwait(false);
                    if (basedata.code == 0) {
                        var d = JsonConvert.DeserializeObject<JArray>(basedata.content);
                        if (d.Count > 0) {
                            shopno = d[0]["no"].ToString();
                            await _memcachedClient.AddAsync(cachekey, shopno, 72000).ConfigureAwait(false);
                        }
                    }
                }
                payment.ShopNO = shopno;

                var command = new Application.Commands.CreatePaymentRequestCommand(payment, req.Id, PaymentScenario.Waimai);
                var result1 = await _mediator.Send(command).ConfigureAwait(false);

                var pay = new PaymentRsp {
                    OrderCode = result1.Ordercode,
                    Payed = result1.Payed,
                    Paymentrequest = result1.Paymentrequest,
                    PayMethod = result1.PayMethod.ToInt32(0)
                };
                return new BaseResult<PaymentRsp>(pay, 0, "");
            }
            if (result.Code == 0 && result.Content.Payed) {
                var cmd3 = new OrderCreateMemberCouponCommand { ActivityId = 6, OrderCode = result.Content.OrderCode };
                var rsp = await _mediator.Send(cmd3).ConfigureAwait(false);
                logger.Trace($"OrderCreateMemberCouponCommand:{ result.Content.OrderCode},{JsonConvert.SerializeObject(rsp)}");
            }


            return result;

        }

        /// <summary>
        /// 
        ///获取订单详情
        /// </summary>
        /// <returns>The detail.</returns>
        /// <param name="req">Req.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<CakeOrderBaseRespone>> GetDetail([FromBody] GetOrderDetailReq req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }

            var mobile = MemberHelper.GetMobile(token);
            var cmd = new Casamiel.Application.Commands.Waimai.v3.GetOrderDetailCommand(req.OrderCode, mobile,LoginInfo.Item3);
            var result = await _mediator.Send(cmd).ConfigureAwait(false);
            return result;
        }

    }
}
